<?php

/*
	Class: Communitas_Integrate_Model_Catalog_Product_Api

	About: Authors
		Tyler Vigeant, Rich Joslin

	About: License
		<http://communit.as/docs/license>
*/
class Communitas_Integrate_Model_Catalog_Product_Api extends Mage_Catalog_Model_Product_Api {

	public function __construct() {
		parent::__construct();
	}

	public function items($filters = null, $store = null) {
		return parent::items($filters, $store);
	}

	public function getProducts($filters = null, $store = null, $attributes = null, $sort = null) {
		$result = array();

		$collection = Mage::getModel('catalog/product')->getCollection()
            ->setStoreId($this->_getStoreId($store));

		foreach ($attributes as $attribute) {
			if( $attribute!='final_price' ){
				$collection->addAttributeToSelect($attribute);
			}
		}

		if (array_key_exists('__no_children', $filters)) {
			## Add the super link table to the select
			$collection->joinTable(
				'catalog_product_super_link',
				'product_id=entity_id',
				array('parent_id'),
				null,
				'left'
			);

			## Filter out products with a parent
			$collection->getSelect()->where("`catalog_product_super_link`.`parent_id` IS NULL");

			## Don't confuse the filter
			unset($filters['__no_children']);
		}

		if (!is_null($sort)) {
			$collection->addAttributeToSort($sort['attribute'], $sort['direction']);
		}

		## Detect the limit filter, then clear it
		if (array_key_exists('__limit', $filters)) {
			$per_page = $filters['__limit'];
			$cur_page = (isset($filters['__page'])) ? $filters['__page'] : 0;

			## Clear this data so that it will not mess with Magento filtering
			unset($filters['__limit']);
			unset($filters['__page']);
		} else {
			$limit = false;
		}

		if (is_array($filters)) {
			try {
				foreach ($filters as $field => $value) {
					if ($field == "category_ids") {
						$collection->addAssignedCategoryFilter($value);
						continue;
					}

					if (isset($this->_filtersMap[$field])) {
						$field = $this->_filtersMap[$field];
					}

					$collection->addFieldToFilter($field, $value);
				}
			} catch (Mage_Core_Exception $e) {
				$this->_fault('filters_invalid', $e->getMessage());
			}
		}

		if ($limit !== false) {
			$result['__pagination_per'] = $per_page;
			$result['__pagination_current'] = $cur_page;
			$result['__pagination_total'] = $collection->getSize();

			$collection->setPageSize($per_page);
			## Pager correction: Communitas pager starts on 0, Magento/Zend starts on 1. Done at the collection level to not upset Communitas
			$collection->setCurPage($cur_page + 1);
		}

		foreach ($collection as $product) {
			$tmp_result = array(
				'product_id'   => $product->getId(),
				'sku'          => $product->getSku(),
				'name'         => $product->getName(),
				'set'          => $product->getAttributeSetId(),
				'type'         => $product->getTypeId(),
				'category_ids' => $product->getCategoryIds(),
				'categories'   => $product->getCategoryIds(),
				'parent_id'    => $product->getParentId(),
			);
		
			if( in_array('final_price', $attributes) ){
				## Mage_Catalog_Model_Product
				$_product = $this->_getProduct($product->getId(), $store);
				$tmp_result['final_price'] = $_product->getFinalPrice();
			}
			
			foreach ($attributes as $attrib) {
				if( $attrib != 'final_price' ){
					$methodname = "get".str_replace(" ", "", ucwords($attrib));
					$tmp_result[$attrib] = $product->$methodname();
				}
			}
			$result[] = $tmp_result;
		}

		return $result;
	}

	public function search($query, $store = null, $attributes = null) {
		$result = array();

		$collection = Mage::helper('catalogSearch')->getQuery()->getResultCollection()
            ->addAttributeToSelect('name')
            ->addAttributeToSelect('description')
			->addFieldToFilter('status', '1')
			->addSearchFilter($query);

		foreach ($attributes as $attribute) {
			$collection->addAttributeToSelect($attribute);
		}

		## Add the super link table to the select
		$collection->joinTable(
			'catalog_product_super_link',
			'product_id=entity_id',
			array('parent_id'),
			null,
			'left'
		);
		
		## Filter out products with a parent
		$collection->getSelect()->where("`catalog_product_super_link`.`parent_id` IS NULL");

        $collection = $collection->load();

		foreach ($collection as $product) {
			$tmp_result = array(
				'product_id'   => $product->getId(),
				'sku'          => $product->getSku(),
				'name'         => $product->getName(),
				'set'          => $product->getAttributeSetId(),
				'type'         => $product->getTypeId(),
				'category_ids' => $product->getCategoryIds(),
				'parent_id'    => $product->getParentId(),
			);
			foreach ($attributes as $attrib) {
				$methodname = "get".str_replace(" ", "", ucwords($attrib));
				$tmp_result[$attrib] = $product->$methodname();
			}
			$result[] = $tmp_result;
		}

		return $result;
	}

	public function getUsedAttributes($cat_id, $store = null) {
		$products = $this->getProducts(array('category_ids' => array($cat_id)), $store);
		return array();
	}

	public function info($productId, $store = null, $attributes = null) {
		// return parent::info($productId, $store, $attributes);

		$product = $this->_getProduct($productId, $store);

		if (!$product->getId()) {
			$this->_fault('not_exists');
		}

		$result = array( // Basic product data
			'product_id' 	=> $product->getId(),
			'sku'        	=> $product->getSku(),
			'set'        	=> $product->getAttributeSetId(),
			'type'       	=> $product->getTypeId(),
			'categories'	=> $product->getCategoryIds(),
			'websites'   	=> $product->getWebsiteIds(),
			'price'		 	=> $product->getPrice(),
			'final_price'	=> $product->getFinalPrice(),
		);
		
		if( in_array('special_price', $attributes) ){
			$attributes[] = 'special_from_date';
			$attributes[] = 'special_to_date';
		}

		$result['comparable_attributes'] = array();

		foreach ($product->getTypeInstance()->getEditableAttributes() as $attribute) {
			if ($this->_isAllowedAttribute($attribute, $attributes)) {
				$result[$attribute->getAttributeCode()] = $product->getData($attribute->getAttributeCode());
				if ($attribute->getIsComparable() == 1) {
					$result['comparable_attributes'][] = $attribute->getAttributeCode();
				}
			}
		}

		return $result;
	}

	public function create($type, $set, $sku, $productData) {
		return parent::create($type, $set, $sku, $productData);
	}

	public function update($productId, $productData = array(), $store = null)
   {
        $product = $this->_getProduct($productId, $store);

        if (!$product->getId()) {
            $this->_fault('not_exists');
        }

        $editableAttributes = $product->getTypeInstance()->getEditableAttributes();
		  
        foreach ($productData as $code => $value) {

            $attribute = isset($editableAttributes[$code]) ? $editableAttributes[$code] : false;

            if ( $attribute ){
                if (is_string($store) || (is_int($store) && $store>0)) {
                    if ($this->_isAllowedAttribute($attribute)) {
                        /**
                         * if value is '__use_default', need to set up actual null value
                         */
                        if (strtolower($value)==='__use_default') {
                            $value = null;
                        }
                        $product->setData(
                            $attribute->getAttributeCode(),
                            $value
                        );
                    }
                 } else {
                    if (is_null($value)){
                        continue;
                    }
                    if (isset($value)){
                        if ($this->_isAllowedAttribute($attribute)) {
                            $product->setData(
                                $attribute->getAttributeCode(),
                                $value
                            );
                        }
                    }
                 }
            }
        }

        $this->_prepareDataForSave($product, $productData);

        try {
            if (is_array($errors = $product->validate())) {
                $this->_fault('data_invalid', implode("\n", $errors));
            }
        } catch (Mage_Core_Exception $e) {
            $this->_fault('data_invalid', $e->getMessage());
        }

        try {
            $product->save();
        } catch (Mage_Core_Exception $e) {
            $this->_fault('data_invalid', $e->getMessage());
        }

        return true;
    }

	protected function _prepareDataForSave ($product, $productData) {
		return parent::_prepareDataForSave($product, $productData);
	}

	public function setSpecialPrice($productId, $specialPrice = null, $fromDate = null, $toDate = null, $store = null) {
		return parent::setSpecialPrice($productId, $specialPrice, $fromDate, $toDate, $store);
	}

	public function getSpecialPrice($productId, $store = null) {
		return parent::getSpecialPrice($productId, $store);
	}

	public function delete($productId) {
		return parent::delete($productId);
	}

	public function getWebsites() {
		$collection = Mage::getModel('core/website')->getCollection()->joinGroupAndStore();
		$websites = $collection->getData();

		if (count($websites) >= 1) {
			foreach ($websites as $key => $website) {
				if ($website['website_id'] == '0') {
					unset($websites[$key]);
					break;
				}
			}
			return $websites;
		} else {
			return array();
		}
	}

	public function getIdByUrlKey($url_key, $store = null) {
		$collection = Mage::getModel('catalog/product')->getCollection()
			->setStoreId($this->_getStoreId($store));
		
		## Add the super link table to the select
		$collection->joinTable(
			'catalog_product_super_link',
			'product_id=entity_id',
			array('parent_id'),
			null,
			'left'
		);

		## Filter out products with a parent
		$collection->getSelect()->where("`catalog_product_super_link`.`parent_id` IS NULL");
		
		$collection->addFieldToFilter('url_key', $url_key);
		
		foreach ($collection as $product) {
			$result = $product->getId();
			continue; // we only need the first one
		}
		return $result;
	}
}
